package com.iqismart.shorturl.utils;

/**
 * @Description 10进制、62进制互转
 * @Auther sty
 * @createTime 2019-10-14 12:07
 */
public class Ten2Sixty {
    /**
     * 初始化 62 进制数据，索引位置代表字符的数值，比如 A代表10，z代表61等
     */
    //打乱
    //private static String chars = "gE2VYf5aWiR9MdQZzkSbuBcrK74nGXHL0vpxDyOhwCNqIlms8eTtFU6JAoP31j";
//    private static String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static String chars = "yL827uhgNGHqkFVrcAlOwITeQfCP53nDzUSbZsYKx4E6tXM0idWoB1v9apJRjm";
    private static int scale = 62;
    static {
        /*List<String> list = new ArrayList<>();
        for (char c : chars.toCharArray()) {
            list.add(c+"");
        }
        Collections.shuffle(list);
        StringBuffer sb = new StringBuffer();
        for (String s : list) {
            sb.append(s);
        }
        chars = sb.toString();*/
    }


    /**
     * 将数字转为62进制
     *
     * @param num    Long 型数字
     * @return 62进制字符串
     */
    public static String encode(long num) {
        StringBuilder sb = new StringBuilder();
        int remainder = 0;

        long random =  Double.valueOf(Math.random()*10).longValue();
        num =  Long.parseLong(random+""+num);


        while (num > scale - 1) {
            /**
             * 对 scale 进行求余，然后将余数追加至 sb 中，由于是从末位开始追加的，因此最后需要反转（reverse）字符串
             */
            remainder = Long.valueOf(num % scale).intValue();
            sb.append(chars.charAt(remainder));

            num = num / scale;
        }

        sb.append(chars.charAt(Long.valueOf(num).intValue()));
        String value = sb.reverse().toString();
        //StringUtils.leftPad(value, length, '0')
        return value;
    }

    /**
     * 62进制字符串转为数字
     *
     * @param str 编码后的62进制字符串
     * @return 解码后的 10 进制字符串
     */
    public static long decode(String str) {
        /**
         * 将 0 开头的字符串进行替换
         */
        str = str.replace("^0*", "");
        long num = 0;
        int index = 0;
        for (int i = 0; i < str.length(); i++) {
            /**
             * 查找字符的索引位置
             */
            index = chars.indexOf(str.charAt(i));
            /**
             * 索引位置代表字符的数值
             */
            num += (long) (index * (Math.pow(scale, str.length() - i - 1)));
        }

        num = Long.parseLong(String.valueOf(num).substring(1));

        return num;

    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        final long num = 10000000;
        for (int i = 0; i < 100; i++) {
            System.out.println("62进制：" + encode(num+1*i));
        }

        System.out.println("62进制：" + encode(10000));
        System.out.println("10进制：" + decode("O0AM"));
        System.out.println("10进制：" + decode("GEJ7"));
    }
}
